//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<XEditCtrl.h>
///	@path	~/src/gui/xgui/
///	@date	2008/06/08
///	@desc	.

#pragma once

#include "xeres.h"

#include "graphics/animation/animation.h"
#include "graphics/animation/controller.h"

#include "gui/shifter.h"
#include "gui/IGuiControl.h"
#include "gui/style/style.h"
#include "gui/style/uniscribe.h"

namespace xeres {

	/*!
		\class	XEditCtrl
		\brief	Simple edit control implementation, both for UI or DX.
	*/
	class XEditCtrl : public IGuiControl
	{
	public:

		/// \ctor
		XEditCtrl( const Rect<int>& placement , Ref<StyleFont> font );

		/// \ctor
		XEditCtrl( void );

		/// \dtor
		~XEditCtrl( void );

		DECL_IOBJECT_CLASS_DYNAMIC( XEditCtrl , IGuiControl );

		/// \name XGui Component Attributes
		//@{

		/// \brief	Set size of component.
		virtual bool SetSize( const Pair<int>& size );

		/// \brief	Set placement.
		virtual bool SetPlacement( const Rect<int>& placement );

		/// \brief	Determine if it's edit control (desired special process).
		virtual bool IsEditControl( void ) const { return true; }

		//@}

		/// \name Message Passing
		//@{

		///	\brief	Process key input message.
		virtual HandleInput OnKeyInput( Updater& updater );

		///	\brief	Process mouse input message.
		virtual HandleInput OnMouseInput( Updater& updater );

		/// \brief	Call when focus in.
		virtual void OnFocusIn( Updater& updater , RefWeak<IGuiComp> last );

		/// \brief	Call when focus out.
		virtual void OnFocusOut( Updater& updater , RefWeak<IGuiComp> next );

		/// \brief	Call when close window.
		virtual void OnClose( void ) { m_onChange = NULL; m_onDefault = NULL; }

		//@}

		/// \name Presentation Manipulation
		//@{

		/// \brief	Tick update.
		virtual void Tick( Updater& updater , float dTime );

		/// \brief	Draw XGUI component to composition.
		virtual void Draw( Composition& composition );

		//@}

		///	\brief		Set font of text.
		void SetFont( RefWeak<StyleFont> font );

		///	\brief		Set control edit as password.
		void SetPassword( void );

		///	\brief		Select all text.
		void SelectAll( void );

		///	\brief
		void SetCaretTimer( void );

		///	\brief		Clear entered text.
		void ClearText();

		///	\brief		Set editing text.
		void SetText( const WString& text , bool bSelected );

		///	\brief		Copy selected text to clipboard.
		void CopyToClipboard();

		///	\brief		Paste text from clipboard.
		void PasteFromClipboard();

		///	\brief		Get text rectangle.
		void GetRectText( RECT& rcText );

		///	\brief		Place caret at specific position.
		void PlaceCaret( int nCP );

		///	\brief		Delete selection text.
		void DeleteSelectionText( void );

		///	\brief
		void ResetCaretBlink( bool ResetTimer = false );

		///	\brief		Get control text.
		const WString& GetText( void ) const { return m_text.GetString(); }

		///	\brief		Set change callback.
		void SetOnText( function<void()> call ) { m_onChange = call; }

		/// \brief		Set on return callback.
		void SetOnDefault( function<bool(bool)> call ) { m_onDefault = call; }

		/// \brief		Call on text.
		void OnText( void );

	private:

		// internal process character input
		HandleInput ProcessInput( const KeyInput &input );

		// get region of text
		inline int TextLeft( void ) const;
		inline int TextTop( void ) const;
		inline int TextRight( void ) const;
		inline int TextBottom( void ) const;

	//@ data

		Rect<int>		m_rect;			// rectangle in parent space
		Ref<StyleFont>	m_font;
		Uniscribe		m_text;			// Buffer to hold text

		int      		m_nBorder;      // Border of the window
		int      		m_nSpacing;     // Spacing between the text and the edge of border
		int      		m_nCaret;       // Caret position, in characters
		int      		m_nSelStart;    // Starting position of the selection. The caret marks the end.
		int      		m_nFirstVisible;// First visible character in the edit control

		bool     		m_bCaretOn;     // Flag to indicate whether caret is currently visible
		bool			m_bEntered;		// mouse entered control
		bool     		m_bInsertMode;  // If true, control is in insert mode. Else, overwrite mode.
		bool			m_bMenuLoop;	// inside menu loop

		bool			m_bActive;		// active
		bool			m_bMouseDrag;	// True to indicate drag in progress
		bool			m_bHideCaret;	// If true, we don't render the caret.
		bool			m_isPassword;	// is a password edit control

		// shifters
		AttrShifter		m_caretFlash;

		// short cut map
		//KeyMap			m_hotkey;

		// callbacks
		function<void()>		m_onChange;
		function<bool(bool)>	m_onDefault;
	};

} // namespace xeres
